import React from "react"; import { Alert, Keyboard, Pressable, Text, TouchableWithoutFeedback, View, } from "react-native"; import Animated, { useAnimatedKeyboard, useAnimatedStyle, } from "react-native-reanimated"; import { router, Stack, useLocalSearchParams } from "expo-router"; import TagPill from "@/components/bookmarks/TagPill"; import FullPageError from "@/components/FullPageError"; import { Button } from "@/components/ui/Button"; import { Divider } from "@/components/ui/Divider"; import FullPageSpinner from "@/components/ui/FullPageSpinner"; import { Input } from "@/components/ui/Input"; import { Skeleton } from "@/components/ui/Skeleton"; import { useToast } from "@/components/ui/Toast"; import { ChevronRight } from "lucide-react-native"; import { useAutoRefreshingBookmarkQuery, useDeleteBookmark, useUpdateBookmark, } from "@karakeep/shared-react/hooks/bookmarks"; import { BookmarkTypes, ZBookmark } from "@karakeep/shared/types/bookmarks"; import { isBookmarkStillTagging } from "@karakeep/shared/utils/bookmarkUtils"; function TagList({ bookmark }: { bookmark: ZBookmark }) { return ( {isBookmarkStillTagging(bookmark) ? ( ) : ( bookmark.tags.length > 0 && ( <> {bookmark.tags.map((t) => ( ))} ) )} router.push(`/dashboard/bookmarks/${bookmark.id}/manage_tags`) } className="flex w-full flex-row justify-between gap-3 px-4" > Manage Tags ); } function ManageLists({ bookmark }: { bookmark: ZBookmark }) { return ( router.push(`/dashboard/bookmarks/${bookmark.id}/manage_lists`) } className="flex w-full flex-row justify-between gap-3 rounded-lg bg-white px-4 py-2 dark:bg-accent" > Manage Lists ); } function TitleEditor({ bookmarkId, title, }: { bookmarkId: string; title: string; }) { const { mutate, isPending } = useUpdateBookmark(); return ( mutate({ bookmarkId, title: ev.nativeEvent.text ? ev.nativeEvent.text : null, }) } defaultValue={title ?? ""} /> ); } function NotesEditor({ bookmark }: { bookmark: ZBookmark }) { const { mutate, isPending } = useUpdateBookmark(); return ( mutate({ bookmarkId: bookmark.id, note: ev.nativeEvent.text, }) } defaultValue={bookmark.note ?? ""} /> ); } const ViewBookmarkPage = () => { const { slug } = useLocalSearchParams(); const { toast } = useToast(); if (typeof slug !== "string") { throw new Error("Unexpected param type"); } const { mutate: deleteBookmark, isPending: isDeletionPending } = useDeleteBookmark({ onSuccess: () => { router.replace("dashboard"); toast({ message: "The bookmark has been deleted!", showProgress: false, }); }, }); const keyboard = useAnimatedKeyboard(); const animatedStyles = useAnimatedStyle(() => ({ marginBottom: keyboard.height.value, })); const { data: bookmark, isPending, refetch, } = useAutoRefreshingBookmarkQuery({ bookmarkId: slug, }); if (isPending) { return ; } if (!bookmark) { return ( refetch()} /> ); } const handleDeleteBookmark = () => { Alert.alert( "Delete bookmark?", "Are you sure you want to delete this bookmark?", [ { text: "Cancel", style: "cancel" }, { text: "Delete", onPress: () => deleteBookmark({ bookmarkId: bookmark.id }), style: "destructive", }, ], ); }; let title = null; switch (bookmark.content.type) { case BookmarkTypes.LINK: title = bookmark.title ?? bookmark.content.title; break; case BookmarkTypes.TEXT: title = bookmark.title; break; case BookmarkTypes.ASSET: title = bookmark.title ?? bookmark.content.fileName; break; } return ( ( { if (router.canGoBack()) { router.back(); } else { router.replace("dashboard"); } }} > Done ), }} />